import { isProxy, toRaw } from 'vue'
import type { menuType } from '@/layout/type'
import { staticRoutes } from './index'
import { useUserStore } from '@/store/modules/user'
/**
 * @description 根据路由过滤出有权限的菜单
 * @param useAuth 是否是最高权限角色
 * @param routesToFilter staticRoutes
 * @returns routes menu
 */
const filterMenus = (
  useAuth: boolean = false,
  routesToFilter = staticRoutes
): menuType[] => {
  const userStore = useUserStore()
  return routesToFilter
    .reduce((acc: menuType[], route: any) => {
      const filteredChildren = route.children
        ? filterMenus(useAuth, route.children)
        : []

      // 如果父节点的 path 为 '/', 则将 children 提升到当前层级
      if (route.path === '/') {
        acc.push(...filteredChildren)
      } else {
        // 检查子节点中是否有 meta.menu 为 true 的情况
        const hasMenuInChildren = filteredChildren.some(
          child => child.meta?.menu
        )

        // 检查 userStore 中的 menuAuth 是否包含当前 route 的 name
        // 如果 useAuth 为 true, 则需要检查 userStore 中的 menuAuth 是否包含当前 route 的 name
        const isRouteAuthorized = useAuth
          ? true
          : userStore.menuAuth.has(route.name)

        if ((route.meta?.menu && isRouteAuthorized) || hasMenuInChildren) {
          acc.push({ ...route, children: filteredChildren })
        }
      }

      return acc
    }, [])
    .sort((a, b) => {
      // 根据 rank 字段进行排序，如果 rank 不存在则默认为 0
      const rankA = a.meta?.rank ?? 0
      const rankB = b.meta?.rank ?? 0
      return rankA - rankB
    })
}

/**
 * @description 过滤出所有第一层级有权限的菜单
 * @param useAuth 是否是最高权限角色
 * @param routesToFilter staticRoutes
 * @returns routes menu 第一层级
 */
const filterFirstLevelMenus = (
  useAuth: boolean = false,
  routesToFilter = staticRoutes
) => {
  return filterMenus(useAuth, routesToFilter)
    .filter((item: any) => item.path !== '/')
    .map((item: any) => {
      // 移除 children 字段
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const { children, ...rest } = item
      return rest
    })
    .sort((a, b) => {
      // 根据 rank 字段进行排序，如果 rank 不存在则默认为 0
      const rankA = a.meta?.rank ?? 0
      const rankB = b.meta?.rank ?? 0
      return rankA - rankB
    })
}

/**
 * @description 查找指定路径的父级路径
 * @param path
 * @param routes
 * @returns
 */
const processRoutes = (routes = staticRoutes): any[] => {
  return routes.flatMap((route: any) => {
    if (route.name === 'Home' && route.children) {
      // 提升子路由到与 Welcome 同级
      return route.children
    } else {
      // 保留原路由结构
      return route
    }
  })
}

/** 通过指定 `key` 获取父级路径集合，默认 `key` 为 `path` */
function getParentPaths(value: string, routes: menuType[], key = 'path') {
  // 深度遍历查找
  function dfs(routes: menuType[], value: string, parents: string[]) {
    for (let i = 0; i < routes.length; i++) {
      const item = routes[i]
      // 返回父级path
      if (item[key] === value) return parents
      // children不存在或为空则不递归
      if (!item.children || !item.children.length) continue

      // 往下查找时将当前path入栈
      parents.push(item.path)

      if (dfs(item.children, value, parents).length) return parents
      // 深度遍历查找未找到时当前path 出栈
      parents.pop()
    }
    // 未找到时返回空数组
    return []
  }
  return dfs(routes, value, [])
}

/** 查找对应 `path` 的路由信息 */
function findRouteByPath(path: string, routes: menuType[]) {
  let res = routes.find((item: { path: string }) => item.path == path)
  if (res) {
    return isProxy(res) ? toRaw(res) : res
  } else {
    for (let i = 0; i < routes.length; i++) {
      if (
        routes[i].children instanceof Array &&
        routes[i].children.length > 0
      ) {
        res = findRouteByPath(path, routes[i].children)
        if (res) {
          return isProxy(res) ? toRaw(res) : res
        }
      }
    }
    return null
  }
}

export {
  filterMenus,
  filterFirstLevelMenus,
  processRoutes,
  getParentPaths,
  findRouteByPath
}
